04. Unit Tests

Section 3: Write Unit Tests and Refactor Project to Support Unit Tests

In this section, you will write unit tests for the Security Service. Each of the requirements below should be verified by one or more unit tests. Make sure to put these unit tests in a new package that has the same name as the package containing the Security Service.

You do NOT need to test the Image Service or the Repository, so you should use @Mocks to help substitute dependencies and keep the scope of each unit test narrow. You should use JUnit 5 features like @ParameterizedTest and ArgumentMatchers to ensure your tests cover branching conditions.

Each of the requirements below should be verified by one or more unit tests. All of these test the Security Service, so make sure your tests don't depend on the implementation of the Repository or the Image Service. Remember, you can use Mocks* to replace these services in your unit tests.*

You should also write interfaces to describe the necessary behaviors of your dependencies to make them easier to Mock. We’re already using a SecurityRepository interface, but we have no interface to describe the behavior of our Image Service. Create an interface that makes it easy to test our application regardless of whether we’re using the AwsImageService or FakeImageService. Remove references to the ImageService from the GUI and use the SecurityService to call the ImageService, so that you can mock the behavior of the ImageService.

Optional Stand Out Task: Connect Your Project to the AWS Image Recognition Library

Once you have created an interface for your image service, complete the steps described in the AwsImageService to create credentials and provide them in a properties file for your application. Change the ImageService implementation class in the CatpointGui class to use the AwsImageService instead of the FakeImageService. Try submitting different types of images and see what comes back!

**Armed and Ready to Go!**

Armed and Ready to Go!

While you are writing tests, it's possible you may need to refactor the application in order to make all of the requirements testable. For example, parts of the business logic may be contained in the GUI or repository classes. You may have to move this logic into the security service to be tested.

Remember, a failing unit test could mean one of two things:

  1. Your unit test is faulty.
  2. Something in your program isn't working.

Some of these requirements might not be properly implemented, so, even if you write the correct unit test, it might still fail. You will fix any faulty or missing requirements in the next section.

Application Requirements to Test:

  1. If alarm is armed and a sensor becomes activated, put the system into pending alarm status.
  2. If alarm is armed and a sensor becomes activated and the system is already pending alarm, set the alarm status to alarm.
  3. If pending alarm and all sensors are inactive, return to no alarm state.
  4. If alarm is active, change in sensor state should not affect the alarm state.
  5. If a sensor is activated while already active and the system is in pending state, change it to alarm state.
  6. If a sensor is deactivated while already inactive, make no changes to the alarm state.
  7. If the image service identifies an image containing a cat while the system is armed-home, put the system into alarm status.
  8. If the image service identifies an image that does not contain a cat, change the status to no alarm as long as the sensors are not active.
  9. If the system is disarmed, set the status to no alarm.
  10. If the system is armed, reset all sensors to inactive.
  11. If the system is armed-home while the camera shows a cat, set the alarm status to alarm.

Reminder: If you find yourself relying on the behavior of another service, you may want to consider using a Mock!